package org.road0329.dlt698.tools;

import com.alibaba.fastjson2.JSON;
import org.road0329.dlt698.DataUtils;
import org.road0329.dlt698.asn1.axdr.AxdrEnum;
import org.road0329.dlt698.axdr.Data;
import org.road0329.dlt698.axdr.MS;
import org.road0329.dlt698.axdr.RCSD;
import org.road0329.dlt698.axdr.TI;
import org.road0329.dlt698.bean.DataKey;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ParseTool {
    public static String parseData(Data data) {
        Map<String, Object> map = new HashMap<>();
        String frameData = null;
        int choiceIndexValue = data.getChoiceIndex().getValue();
        switch (choiceIndexValue) {
            case 0:
                map.put(DataKey.NULL_DATA, "");
                break;
            case 1:
                List<String> listArray = new ArrayList<>();
                for (int i = 0; i < data.getArray().size(); i++) {
                    listArray.add(parseData(data.getArray().get(i)));
                }
                map.put(DataKey.ARRAY, listArray);
                break;
            case 2:
                List<String> listStructure = new ArrayList<>();
                for (int i = 0; i < data.getStructure().size(); i++) {
                    listStructure.add(parseData(data.getStructure().get(i)));
                }
                map.put(DataKey.STRUCTURE, listStructure);
                break;
            case 3:
                map.put(DataKey.BOOL, DataUtils.bytesToHexString(data.getBool().getDataCode(), 0, data.getBool().getDataCode().length));
                break;
            case 4:
                map.put(DataKey.BIT_STRING, data.getBitString().toString());
                break;
            case 5:
                map.put(DataKey.DOUBLE_LONG, DataUtils.bytesToHexString(data.getDoubleLong().getDataCode(), 0, data.getDoubleLong().getDataCode().length));
                break;
            case 6:
                map.put(DataKey.DOUBLE_LONG_UNSIGNED, DataUtils.bytesToHexString(data.getDoubleLongUnsigned().getDataCode(), 0, data.getDoubleLongUnsigned().getDataCode().length));
                break;
            case 9:
                map.put(DataKey.OCTET_STRING, data.getOctetString().toString());
                break;
            case 10:
                map.put(DataKey.VISIBLE_STRING, data.getVisibleString().toString());
                break;
            case 12:
                map.put(DataKey.UTF8_STRING, data.getUtf8String().toString());
                break;
            case 15:
                map.put(DataKey.INTEGER, DataUtils.bytesToHexString(data.getInteger().getDataCode(), 0, data.getInteger().getDataCode().length));
                break;
            case 16:
                map.put(DataKey.LONG, DataUtils.bytesToHexString(data.getLongdata().getDataCode(), 0, data.getLongdata().getDataCode().length));
                break;
            case 17:
                map.put(DataKey.UNSIGNED, DataUtils.bytesToHexString(data.getUnsigned().getDataCode(), 0, data.getUnsigned().getDataCode().length));
                break;
            case 18:
                map.put(DataKey.LONG_UNSIGNED, DataUtils.bytesToHexString(data.getLongUnsigned().getDataCode(), 0, data.getLongUnsigned().getDataCode().length));
                break;
            case 20:
                map.put(DataKey.LONG64, DataUtils.bytesToHexString(data.getLong64().getDataCode(), 0, data.getLong64().getDataCode().length));
                break;
            case 21:
                map.put(DataKey.LONG64_UNSIGNED, DataUtils.bytesToHexString(data.getLong64Unsigned().getDataCode(), 0, data.getLong64Unsigned().getDataCode().length));
                break;
            case 22:
                map.put(DataKey.ENUM_KEY, DataUtils.bytesToHexString(data.getEnumdata().getDataCode(), 0, data.getEnumdata().getDataCode().length));
                break;
            case 23:
                map.put(DataKey.FLOAT32, data.getFloat32().toString());
                break;
            case 24:
                map.put(DataKey.FLOAT64, data.getFloat64().toString());
                break;
            case 25:
                map.put(DataKey.DATE_TIME, DataUtils.bytesToHexString(data.getDateTime().getDataCode(), 0, data.getDateTime().getDataCode().length));
                break;
            case 26:
                map.put(DataKey.DATE, DataUtils.bytesToHexString(data.getDate().getDataCode(), 0, data.getDate().getDataCode().length));
                break;
            case 27:
                map.put(DataKey.TIME, DataUtils.bytesToHexString(data.getTime().getDataCode(), 0, data.getTime().getDataCode().length));
                break;
            case 28:
                map.put(DataKey.DATE_TIME_S, DataUtils.bytesToHexString(data.getDateTimeS().getDataCode(), 0, data.getDateTimeS().getDataCode().length));
                break;
            case 80:
                map.put(DataKey.OI, DataUtils.bytesToHexString(data.getOi().getDataCode(), 0, data.getOi().getDataCode().length));
                break;
            case 81:
                map.put(DataKey.OAD, DataUtils.bytesToHexString(data.getOad().getDataCode(), 0, data.getOad().getDataCode().length));
                break;
            case 82:
                Map<String, Object> roadData = new HashMap<>();
                Map<String, Object> seqOad = new HashMap<>();
                List<String> seqOadList = new ArrayList<>();
                for (int i = 0; i < data.getRoad().getOads().size(); i++) {
                    Data value = new Data();
                    value.setOad(data.getRoad().getOads().get(i));
                    seqOadList.add(parseData(value));
                }
                roadData.put("OAD", DataUtils.bytesToHexString(data.getRoad().getOad().getDataCode(), 0, data.getRoad().getOad().getDataCode().length));
                roadData.put("seq_oad", seqOadList);
                map.put(DataKey.ROAD, roadData);
                break;
            case 83:
                map.put(DataKey.OMD, DataUtils.bytesToHexString(data.getOmd().getDataCode(), 0, data.getOmd().getDataCode().length));
                break;
            case 84:
                Map<String, Object> tiData = new HashMap<>();
                tiData.put("enum", DataUtils.bytesToHexString(data.getTi().getUnit().getDataCode(), 0, data.getTi().getUnit().getDataCode().length));
                tiData.put("long_unsigned", DataUtils.bytesToHexString(data.getTi().getInter().getDataCode(), 0, data.getTi().getInter().getDataCode().length));
                map.put(DataKey.TI, tiData);
                break;
            case 85:
                map.put(DataKey.TSA, data.getTsa().toString());
                break;
            case 86:
                map.put(DataKey.MAC, data.getMac().toString());
                break;
            case 87:
                map.put(DataKey.RN, data.getRn().toString());
                break;
            case 88:
                Map<String, Object> regionData = new HashMap<>();
                Data regionType = new Data();
                AxdrEnum enumData = new AxdrEnum();
                enumData.setDataCode(data.getRegion().getUnit().getDataCode());
                regionType.setEnumData(enumData);
                regionData.put("type", parseData(regionType));
                regionData.put("s_data", parseData(data.getRegion().getSval()));
                regionData.put("e_data", parseData(data.getRegion().getEval()));
                map.put(DataKey.REGION, regionData);
                break;
            case 89:
                map.put(DataKey.SCALER_UNIT, DataUtils.bytesToHexString(data.getScalerUnit().getDataCode(), 0, data.getScalerUnit().getDataCode().length));
                break;
            case 90:
                Object rsdTempData = null;
                switch (data.getRsd().getChoiceIndex().getValue()) {
                    case 0:
                        Map<String, Object> selector0 = new HashMap<>();
                        rsdTempData = selector0;
                        break;
                    case 1:
                        Map<String, Object> selector1 = new HashMap<>();
                        selector1.put("OAD", DataUtils.bytesToHexString(data.getRsd().getS1().getOad().getDataCode(), 0, data.getRsd().getS1().getOad().getDataCode().length));
                        selector1.put("data", parseData(data.getRsd().getS1().getData()));
                        rsdTempData = selector1;
                        break;
                    case 2:
                        Map<String, Object> selector2 = new HashMap<>();
                        selector2.put("OAD", DataUtils.bytesToHexString(data.getRsd().getS2().getOad().getDataCode(), 0, data.getRsd().getS2().getOad().getDataCode().length));
                        selector2.put("s_data", parseData(data.getRsd().getS2().getSval()));
                        selector2.put("e_data", parseData(data.getRsd().getS2().getEval()));
                        selector2.put("unit", parseData(data.getRsd().getS2().getInter()));
                        rsdTempData = selector2;
                        break;
                    case 3:
                        List<Map<String, Object>> s3List = new ArrayList<>();
                        Map<String, Object> selector3 = new HashMap<>();
                        for (int i = 0; i < data.getRsd().getS3().size(); i++) {
                            Map<String, Object> selector02 = new HashMap<>();
                            selector02.put("OAD", DataUtils.bytesToHexString(data.getRsd().getS3().get(i).getOad().getDataCode(), 0, data.getRsd().getS3().get(i).getOad().getDataCode().length));
                            selector02.put("s_data", parseData(data.getRsd().getS3().get(i).getSval()));
                            selector02.put("e_data", parseData(data.getRsd().getS3().get(i).getEval()));
                            selector02.put("unit", parseData(data.getRsd().getS3().get(i).getInter()));
                            s3List.add(selector02);
                        }
                        selector3.put("seq_selector2", s3List);
                        rsdTempData = selector3;
                        break;
                    case 4:
                        Map<String, Object> selector4 = new HashMap<>();
                        selector4.put("date_time_s", DataUtils.bytesToHexString(data.getRsd().getS4().getDts().getDataCode(), 0, data.getRsd().getS4().getDts().getDataCode().length));
                        selector4.put("MS", parseMsData(data.getRsd().getS4().getMs()));
                        rsdTempData = selector4;
                        break;
                    case 5:
                        Map<String, Object> selector5 = new HashMap<>();
                        selector5.put("date_time_s", DataUtils.bytesToHexString(data.getRsd().getS5().getDts().getDataCode(), 0, data.getRsd().getS5().getDts().getDataCode().length));
                        selector5.put("ms", parseMsData(data.getRsd().getS5().getMs()));
                        rsdTempData = selector5;
                        break;
                    case 6:
                        Map<String, Object> selector6 = new HashMap<>();
                        Data s6Inter = new Data();
                        s6Inter.setTi(data.getRsd().getS6().getInter());
                        selector6.put("s_time", DataUtils.bytesToHexString(data.getRsd().getS6().getDtss().getDataCode(), 0, data.getRsd().getS6().getDtss().getDataCode().length));
                        selector6.put("e_time", DataUtils.bytesToHexString(data.getRsd().getS6().getDtse().getDataCode(), 0, data.getRsd().getS6().getDtse().getDataCode().length));
                        selector6.put("ti", parseTIData(data.getRsd().getS6().getInter()));
                        selector6.put("ms", parseMsData(data.getRsd().getS6().getMs()));
                        rsdTempData = selector6;
                        break;
                    case 7:
                        Map<String, Object> selector7 = new HashMap<>();
                        selector7.put("s_time", DataUtils.bytesToHexString(data.getRsd().getS7().getDtss().getDataCode(), 0, data.getRsd().getS7().getDtss().getDataCode().length));
                        selector7.put("e_time", DataUtils.bytesToHexString(data.getRsd().getS7().getDtse().getDataCode(), 0, data.getRsd().getS7().getDtse().getDataCode().length));
                        selector7.put("ti", parseTIData(data.getRsd().getS7().getInter()));
                        selector7.put("ms", parseMsData(data.getRsd().getS7().getMs()));
                        rsdTempData = selector7;
                        break;
                    case 8:
                        Map<String, Object> selector8 = new HashMap<>();
                        selector8.put("s_time", DataUtils.bytesToHexString(data.getRsd().getS8().getDtss().getDataCode(), 0, data.getRsd().getS8().getDtss().getDataCode().length));
                        selector8.put("e_time", DataUtils.bytesToHexString(data.getRsd().getS8().getDtse().getDataCode(), 0, data.getRsd().getS8().getDtse().getDataCode().length));
                        selector8.put("ti", parseTIData(data.getRsd().getS8().getInter()));
                        selector8.put("ms", parseMsData(data.getRsd().getS8().getMs()));
                        rsdTempData = selector8;
                        break;
                    case 9:
                        Map<String, Object> selector9 = new HashMap<>();
                        selector9.put("n_times", DataUtils.bytesToHexString(data.getRsd().getS9().getRecn().getDataCode(), 0, data.getRsd().getS9().getRecn().getDataCode().length));
                        rsdTempData = selector9;
                        break;
                    case 10:
                        Map<String, Object> selector10 = new HashMap<>();
                        selector10.put("n_times", DataUtils.bytesToHexString(data.getRsd().getS10().getRecn().getDataCode(), 0, data.getRsd().getS10().getRecn().getDataCode().length));
                        selector10.put("ms", parseMsData(data.getRsd().getS10().getMs()));
                        rsdTempData = selector10;
                        break;
                }
                map.put(DataKey.RSD, rsdTempData);
                break;
            case 91:
                Object tempData = null;
                switch (data.getCsd().getChoiceIndex().getValue()) {
                    case 0:
                        Data csdOadData = new Data();
                        csdOadData.setOad(data.getCsd().getOad());
                        tempData = parseData(csdOadData);
                        break;
                    case 1:
                        Data csdRoadData = new Data();
                        csdRoadData.setRoad(data.getCsd().getRoad());
                        tempData = parseData(csdRoadData);
                        break;
                }
                map.put(DataKey.CSD, tempData);
                break;
            case 92:
                Object msData = null;
                int msChoiceIndexValue = data.getMs().getChoiceIndex().getValue();
                switch (msChoiceIndexValue) {
                    case 0:
                    case 1:
                        msData = "";
                        break;
                    case 2:
                        Map<String, Object> seqOfU = new HashMap<>();
                        List<String> ms2List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getGroupmtype().size(); i++) {
                            Data un8 = new Data();
                            un8.setUnsigned(data.getMs().getGroupmtype().get(i));
                            ms2List.add(parseData(un8));
                        }
                        seqOfU.put("seq_unsigned", ms2List);
                        msData = seqOfU;
                        break;
                    case 3:
                        Map<String, Object> seqOfTsa = new HashMap<>();
                        List<String> m3List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getGroupmaddr().size(); i++) {
                            Data tsa = new Data();
                            tsa.setTsa(data.getMs().getGroupmaddr().get(i));
                            m3List.add(parseData(tsa));
                        }
                        seqOfTsa.put("seq_tsa", m3List);
                        msData = seqOfTsa;
                        break;
                    case 4:
                        Map<String, Object> seqOfLu = new HashMap<>();
                        List<String> m4List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getGroupsetindex().size(); i++) {
                            Data lu = new Data();
                            lu.setLongUnsigned(data.getMs().getGroupsetindex().get(i));
                            m4List.add(parseData(lu));
                        }
                        seqOfLu.put("seq_long_unsigned", m4List);
                        msData = seqOfLu;
                        break;
                    case 5:
                        Map<String, Object> seqOfR5 = new HashMap<>();
                        List<String> m5List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getRegiontype().size(); i++) {
                            Data region = new Data();
                            region.setRegion(data.getMs().getRegiontype().get(i));
                            m5List.add(parseData(region));
                        }
                        seqOfR5.put("seq_region", m5List);
                        msData = seqOfR5;
                        break;
                    case 6:
                        Map<String, Object> seqOfR6 = new HashMap<>();
                        List<String> m6List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getRegionaddr().size(); i++) {
                            Data region = new Data();
                            region.setRegion(data.getMs().getRegionaddr().get(i));
                            m6List.add(parseData(region));
                        }
                        seqOfR6.put("seq_region", m6List);
                        msData = seqOfR6;
                        break;
                    case 7:
                        Map<String, Object> seqOfR7 = new HashMap<>();
                        List<String> m7List = new ArrayList<>();
                        for (int i = 0; i < data.getMs().getRegionsetindex().size(); i++) {
                            Data region = new Data();
                            region.setRegion(data.getMs().getRegionsetindex().get(i));
                            m7List.add(parseData(region));
                        }
                        seqOfR7.put("seq_region", m7List);
                        msData = seqOfR7;
                        break;
                }
                map.put(DataKey.MS, msData);
                break;
            case 93:
                Map<String, Object> sidData = new HashMap<>();
                sidData.put("double_long_unsigned", DataUtils.bytesToHexString(data.getSid().getIndi().getDataCode(), 0, data.getSid().getIndi().getDataCode().length));
                sidData.put("octet_string", data.getSid().getFdata().toString());
                map.put(DataKey.SID, sidData);
                break;
            case 94:
                Map<String, Object> sidMacData = new HashMap<>();
                sidMacData.put("sid", new HashMap<String, Object>());
                sidMacData.put("mac", data.getSidMac().getMac().toString());
                ((Map<String, Object>) sidMacData.get("sid")).put("double_long_unsigned", DataUtils.bytesToHexString(data.getSidMac().getSid().getIndi().getDataCode(), 0, data.getSidMac().getSid().getIndi().getDataCode().length));
                ((Map<String, Object>) sidMacData.get("sid")).put("octet_string", data.getSidMac().getSid().getFdata().toString());
                map.put(DataKey.SID_MAC, sidMacData);
                break;
            case 95:
                Map<String, Object> comdcbData = new HashMap<>();
                comdcbData.put("baut", DataUtils.bytesToHexString(data.getComdcb().getBaut().getDataCode(), 0, data.getComdcb().getBaut().getDataCode().length));
                comdcbData.put("parity", DataUtils.bytesToHexString(data.getComdcb().getParity().getDataCode(), 0, data.getComdcb().getParity().getDataCode().length));
                comdcbData.put("datab", DataUtils.bytesToHexString(data.getComdcb().getParity().getDataCode(), 0, data.getComdcb().getParity().getDataCode().length));
                comdcbData.put("stopb", DataUtils.bytesToHexString(data.getComdcb().getStopb().getDataCode(), 0, data.getComdcb().getStopb().getDataCode().length));
                comdcbData.put("flow", DataUtils.bytesToHexString(data.getComdcb().getFlow().getDataCode(), 0, data.getComdcb().getFlow().getDataCode().length));
                map.put(DataKey.COMDCB, comdcbData);
                break;
            case 96:
                List<Object> csdList = new ArrayList<>();
                Map<String, Object> rcsdData = new HashMap<>();
                RCSD rcsd = data.getRcsd();
                for (int i = 0; i < rcsd.size(); i++) {
                    Object temp = null;
                    int rcsdChoiceIndexValue = rcsd.get(i).getChoiceIndex().getValue();
                    switch (rcsdChoiceIndexValue) {
                        case 0:
                            Data csdOadData = new Data();
                            csdOadData.setOad(data.getRcsd().get(i).getOad());
                            temp = parseData(csdOadData);
                            break;
                        case 1:
                            Data csdRoadData = new Data();
                            csdRoadData.setRoad(data.getRcsd().get(i).getRoad());
                            temp = parseData(csdRoadData);
                            break;
                    }
                    csdList.add(temp);
                }
                rcsdData.put("seq_csd", csdList);
                map.put(DataKey.RCSD, rcsdData);
                break;
        }
        frameData = JSON.toJSONString(map);
        return frameData;
    }

    public static Map<String, String> parseTIData(TI ti) {

        Map<String, String> tiData = new HashMap<>();
        tiData.put("enum", DataUtils.bytesToHexString(ti.getUnit().getDataCode(), 0, ti.getUnit().getDataCode().length));
        tiData.put("long_unsigned", DataUtils.bytesToHexString(ti.getInter().getDataCode(), 0, ti.getInter().getDataCode().length));
        return tiData;
    }


    public static Object parseMsData(MS ms) {
        Object msData = null;
        switch (ms.getChoiceIndex().getValue()) {
            case 0:
            case 1:
                msData = "";
                break;
            case 2:
                Map<String, List<String>> seqOfU = new HashMap<>();
                List<String> ms2_list = new ArrayList<>();
                for (int i = 0; i < ms.getGroupmtype().size(); i++) {
                    Data un8 = new Data();
                    un8.setUnsigned(ms.getGroupmtype().get(i));
                    ms2_list.add(parseData(un8));
                }
                seqOfU.put("seq_unsigned", ms2_list);
                msData = seqOfU;
                break;
            case 3:
                Map<String, List<String>> seqOfTsa = new HashMap<>();
                List<String> m3_list = new ArrayList<>();
                for (int i = 0; i < ms.getGroupmaddr().size(); i++) {
                    Data tsa = new Data();
                    tsa.setTsa(ms.getGroupmaddr().get(i));
                    m3_list.add(parseData(tsa));
                }
                seqOfTsa.put("seq_tsa", m3_list);
                msData = seqOfTsa;
                break;
            case 4:
                Map<String, List<String>> seqOfLu = new HashMap<>();
                List<String> m4_list = new ArrayList<>();
                for (int i = 0; i < ms.getGroupsetindex().size(); i++) {
                    Data lu = new Data();
                    lu.setLongUnsigned(ms.getGroupsetindex().get(i));
                    m4_list.add(parseData(lu));
                }
                seqOfLu.put("seq_long_unsigned", m4_list);
                msData = seqOfLu;
                break;
            case 5:
                Map<String, List<String>> seqOfR5 = new HashMap<>();
                List<String> m5_list = new ArrayList<>();
                for (int i = 0; i < ms.getRegiontype().size(); i++) {
                    Data region = new Data();
                    region.setRegion(ms.getRegiontype().get(i));
                    m5_list.add(parseData(region));
                }
                seqOfR5.put("seq_region", m5_list);
                msData = seqOfR5;
                break;
            case 6:
                Map<String, List<String>> seqOfR6 = new HashMap<>();
                List<String> m6_list = new ArrayList<>();
                for (int i = 0; i < ms.getRegionaddr().size(); i++) {
                    Data region = new Data();
                    region.setRegion(ms.getRegionaddr().get(i));
                    m6_list.add(parseData(region));
                }
                seqOfR6.put("seq_region", m6_list);
                msData = seqOfR6;
                break;
            case 7:
                Map<String, List<String>> seqOfR7 = new HashMap<>();
                List<String> m7_list = new ArrayList<>();
                for (int i = 0; i < ms.getRegionsetindex().size(); i++) {
                    Data region = new Data();
                    region.setRegion(ms.getRegionsetindex().get(i));
                    m7_list.add(parseData(region));
                }
                seqOfR7.put("seq_region", m7_list);
                msData = seqOfR7;
                break;
        }
        return msData;
    }
}
